<?php
class L10nHelper{
    // Currency symbol/name potions
    const 	CUR_POS_STANDARD	=	'standard';
    const 	CUR_POS_LEFT		=	'left';
    const 	CUR_POS_RIGHT		=	'right';

    // Currency symbol types
    const	CUR_DIS_SYMBOL		=	'symbol';
    const	CUR_DIS_SHORTNAME	=	'shortname';
    const	CUR_DIS_NAME		=	'name';
    const	CUR_DIS_NOSYMBOL	=	'nosymbol';

    // Date format type
    const	DATE_FULL			=	'full';
    const	DATE_LONG			=	'long';
    const	DATE_MEDIUM			=	'medium';
    const	DATE_SHORT			=	'short';

    /**
     * @author hdviet
     * return the current locale
     * format 4 characters [language]_[country code]
     * ex vi_VN
     */
    public static function getLocale() {
        return $_SESSION['lang'];
    }
    
    // TODO ptnguyen
    // Dont hard code 'vi_VN'
    /**
     * covert "NAME" become a column's name in table
     * EX:  changeField(vi_VN, name) -> vn_name
     * 		changeField(en_US , name) -> en_name
     * @param $lang: lange
     * @param $name: column name
     * @return column name in table using localization
     */
    public static function changeField($locale, $name){
    	if (!Zend_Locale::isLocale($locale)) {
    	    return "Unknown locale $locale";
    	}
    	$prefix = substr($locale, 0, 3);
    	return $prefix . $name;
    }
    
    /**
     * try to select a language, if fail keep current language
     * @author hdviet
     *
     * @param $lang
     * @return unknown_type
     */
    public static function selectLanguage($lang) {
        try {
            $translate = new Zend_Translate('gettext',
                                    APP_ROOT . "/local/languages/$lang",
                                    $lang,
                                    array(  'scan'          =>  Zend_Translate::LOCALE_DIRECTORY,
                                            'disableNotices'=>  true
                                ));
             Zend_Registry::set('Zend_Translate', $translate);
             $_SESSION['lang'] = $lang;

        } catch (Exception $ex) {
            //  TODO ptnguyen Log error select language here
        }
    }

    /**
     * @author hdviet
     * return the default locale, which is set in configuration file.
     * format 4 characters [language]_[country code]
     * ex vi_VN
     */
    public static function getDefaultLocale() {
        $config = Celini::configInstance();
        $lang = $config->get('lang');
        return $lang['default'];
    }
    /**
     * @author hdviet
     * check current language is supported or not
     */
    public static function isSupportedLocale($locale) {
        $config = Celini::configInstance();
        $lang = $config->get('lang');
        return isset($lang['list'][$locale]);
    }
    /**
     * @author hdviet
     * return the supported locales list
     * this list is set in configuration file
     */
    public static function getSupportedLocales() {
        $config = Celini::configInstance();
        $lang = $config->get('lang');
        return $lang['list'];
    }

    /**
     * translate
     * @param $data data need to translate
     * @param support 4 input param
     * ex : 2 params are passed
     * L10nHelper::_("name %s age %s",$name,$age);
     * the output name [$name] age [$age]
     */
    public static function _($data, $input = array()){
        $translate = Zend_Registry::get('Zend_Translate');
        //by default return $data
        $result = $data;
        try {
            $result = $translate->_($data);
            $result = vsprintf($result,$input);
        }catch (Exception $ex){
        }
        return $result;
    }

    /**
     * Returns localized date format string used in sql queries
     *
     * @author 	PPDong, 2009-05-29
     * @param 	string 	$value 	Format to get
     * @param 	string	$type 	Type of database
     * @uses 	Current available format are 'YMdHi', 'Ymd' and 'Hi'. These formats are configured in corresponding locale data files
     * @example
     * 		Assumme that current locale is 'vi_VN'
     * 		// Returns '%d/%m/%Y'
     * 		L10nHelper::getSqlDateFormat('Ymd')
     *
     * 		// Returns '%d/%m/%Y %H:%i'
     * 		L10nHelper::getSqlDateFormat('YmdHi')
     */
    public static function getSqlDateFormat($value='Ymd',$type='MySQL'){
        $path	=	 $type. "DateFormat";
        $locale	=	self::getLocale();
        Zend_Locale_Data::clearCache();
        $format = Zend_Locale_Data::getContent($locale, $path, $value);
        return $format;
    }

    /**
     * added by Viet Hoang
     * localize for percentage
     */
    public static function renderPercentage($number){
        $formatted = L10nHelper::renderNumber($number,2);
        $formatted = str_replace('.00', '', $formatted);
        $formatted = str_replace(',00', '', $formatted);
        return $formatted;
    }

    /**
     * Returns a number in a localized currency string
     *
     * @author 	PDong, 2009-05-29
     * @param 	mixed 	$value 		Input number
     * @param 	int 	$decimals 	Number of decimal points in output result
     * @param 	string 	$position 	Positon to display currency symbol
     * @param 	string 	$display	Which currency symbol type to be shown
     * @example
     * 		Assumme that current locale is 'vi-VN'
     * 		// Returns '10.000,7'
     * 		L10nHelper::renderCurrency(10000.678, 1);
     *
     * 		// Returns '10.001 ₫'
     * 		L10nHelper::renderCurrency(10000.678, 0, null, 'symbol');
     *
     * 		// Returns '10.0001 VND'
     * 		L10nHelper::renderCurrency(10000.678, 0, null, 'shortname');
     * 	 */
    public static function renderCurrency($value,$decimals=0,$position=null,$display=null){
        // Validate the passed number
        if(is_null($value) || empty($value)){
            return '0';
        }
        if (!is_numeric($value)) {
            return '0';
        }

        if(is_null($position)){
            $position	=	self::CUR_POS_STANDARD;
        }

        // Get currency format from locale data
        $locale	=	self::getLocale();
        $format	=	'';
        if (Zend_Locale::isLocale($locale)) {
            $format = Zend_Locale_Data::getContent($locale, 'currencynumber');
        }

        $original		=	L10nHelper::renderNumber($value, $decimals);
        $space = '';
        if (iconv_strpos($format, ' ') !== false) {
            $space = ' ';
        }

        $currencyPos	=	iconv_strpos($format,'¤');

        if($currencyPos > 0){
            $value	=	$original. $space. '¤';
        }
        else{
            $value	=	'¤'. $space. $original;
        }

        if ($position !== self::CUR_POS_STANDARD) {
            if ($position == self::CUR_POS_LEFT) {
                $value = '¤' . $space . $original;
            } else {
                $value = $original . $space . '¤';
            }
        }

        // Get the sign to be placed next to the number
        $currency	=	new Zend_Currency();
        $currency->setLocale($locale);
        switch($display) {
            case self::CUR_DIS_SYMBOL:
                $sign = $currency->getSymbol();
                break;
            case self::CUR_DIS_SHORTNAME:
                $sign = $currency->getShortName();
                break;
            case self::CUR_DIS_NAME:
                $sign = $currency->getName();
                break;
            default:
                $sign = '';
                $value = str_replace(' ', '', $value);
                break;
        }

        $value = str_replace('¤', $sign, $value);
        return $value;
    }

    /**
     * Returns an ISO datetime string in a localized datetime string
     *
     * @author	PPDong, 2009-06-01
     * @param 	string	$value	Input ISO datetime string
     * @param 	string 	$format	Desired output format ('full', 'long', 'medium', 'short')
     * @param 	string 	$type	Render type	('date', 'time', 'datetime')
     * @example
     * 		Assumme that current locale is 'vi-VN'
     *
     * 		// Returns '29/05/2009'
     * 		L10nHelper::renderDateTime('2009-05-29 17:40:30', 'short');
     *
     * 		// Returns '17:40'
     * 		return L10nHelper::renderDateTime('2009-05-29 17:40:30', 'short', 'time');
     *
     * 		// Returns '29/05/2009 17:40'
     * 		return L10nHelper::renderDateTime('2009-05-29 17:40:30', 'short', 'datetime');
     *
     *	*/
    public static function renderDateTime($value, $format='short', $type='date'){
        $locale		=	self::getLocale();
        if(is_null($value) || empty($value)){
            return '';
        }
        // Specical case when input data is of formats 'yyyy-mm-00 HH:ii:ss'
        // or 'yyyy-00-00 HH:ii:ss' or '0000-00-00 HH:ii:ss',
        // returns 'mm/yyyy' or 'yyyy' or empty, correspondingly.
        $parts			=	explode(' ', $value);
        //$dates			=	explode('-', $parts[0]);
        $dates			=	split('[/.-]', $parts[0]);
        $specialFormat	=	'';
        $specialDate	=	null;

        if(strlen($dates[2])==1){
            $dates[2]	=	'0'. $dates[2];
        }

        if(strlen($dates[1])==1){
            $dates[1]	=	'0'. $dates[1];
        }

        if($dates[2]=='00' && $dates[1]=='00' && $dates[0]=='0000'){
            return '';
        }

        elseif($dates[2]=='00' && $dates[1]=='00'){
            $specialFormat	=	Zend_Locale_Data::getContent($locale,'specialDateFormat','y');
            $dates[2]		=	$dates[1]	=	1;
            $specialDate	=	new Zend_Date(array('year'=>$dates[0],'month'=>$dates[1],'day'=>$dates[2]));
        }
        elseif($dates[2]=='00'){
            if(strtolower($format)==self::DATE_MEDIUM){
                $value	=	'medium_y_m';
            }
            else{
                $value	=	'short_y_m';
            }
            $specialFormat	=	Zend_Locale_Data::getContent($locale,'specialDateFormat',$value);
            $dates[2]		=	1;
            $specialDate	=	new Zend_Date(array('year'=>$dates[0],'month'=>$dates[1],'day'=>$dates[2]));
        }
        if(!empty($specialFormat)){
            return $specialDate->toString($specialFormat);
        }

        $value	=	$dates[0]. "-". $dates[1]. "-". $dates[2]. " ". (isset($parts[1])?$parts[1]:"");
        switch(strtolower($type)){
            case 'date':
                switch (strtolower($format)){
                    case self::DATE_FULL:
                        $format	=	Zend_Date::DATE_FULL;
                        break;
                    case self::DATE_LONG:
                        $format	=	Zend_Date::DATE_LONG;
                        break;
                    case self::DATE_MEDIUM:
                        $format	=	Zend_Date::DATE_MEDIUM;
                        break;
                    default:
                        $format	=	Zend_Date::DATE_SHORT;
                        break;
                }
                $objDate	=	new Zend_Date($value, Zend_Date::ISO_8601);
                $res		=	$objDate->get($format, $locale);
                return $res;
                    case 'time':
                        switch (strtolower($format)){
                            case self::DATE_FULL:
                                $format	=	Zend_Date::TIME_FULL;
                                break;
                            case self::DATE_LONG:
                                $format	=	Zend_Date::TIME_LONG;
                                break;
                            case self::DATE_MEDIUM:
                                $format	=	Zend_Date::TIME_MEDIUM;
                                break;
                            default:
                                $format	=	Zend_Date::TIME_SHORT;
                                break;
                        }
                        $objDate	=	new Zend_Date($value, Zend_Date::ISO_8601);
                        $res		=	$objDate->get($format,$locale);
                        return $res;
                            case 'datetime':
                                $date		=	self::renderDateTime($value, $format, 'date');
                                $time		=	self::renderDateTime($value, $format, 'time');
                                $pattern	=	Zend_Locale_Data::getContent($locale,'datetime');
                                $pattern	=	str_replace('{0}', $date, $pattern);
                                $pattern	=	str_replace('{1}', $time, $pattern);
                                return $pattern;
                                return '';
        }

    }

    /**
     * Returns a localized datetime string in an ISO formmatted datetime string.
     * Returns empty if the input value is not a valid datetime string in the current locale
     *
     * @author 	PPDong, 2009-06-01
     * @param 	string	$value
     *
     */
    public static function getISODate($value){
        // FIXME: Modify this function to make it fit to all possible cases
        $locale		=	self::getLocale();
        // Case: Array input
        if(is_array($value)){
            if(strlen($value['month'])==1){
                $value['month']	=	"0". $value['month'];
            }
            if(strlen($value['day'])==1){
                $value['day']	=	"0". $value['day'];
            }
            $date	=	$value['year']. "-". $value['month']. "-". $value['day'];
            return $date;
        }
        // Case: "dd/MM/yyyy" or "MM/dd/yyyy". Returns date string.
        if(preg_match('/^(\d{1,2})[\/-](\d{1,2})[\/-](\d{4})$/', $value)){
            $format	=	Zend_Date::DATE_SHORT;
            // Check valid date string
            if(!Zend_Date::isDate($value,$format,$locale)){
                return '';
            }
            $objDate	=	new Zend_Date($value, $format, $locale);
            return $objDate->toString('yyyy-MM-dd');
        }

        // Default: Full format- dd/MM/yyyy HH:ii:ss
        if(!Zend_Date::isDate($value, null, $locale)){
            return '';
        }
        $objDate	=	new Zend_Date($value, $format, $locale);
        return 	$objDate->get(Zend_Date::ISO_8601);
    }

    /**
     * Returns a PHP number in a locaized number string
     *
     * @author 	PPDong, 2009-06-01
     * @param 	mixed 	$value 		Input number
     * @param 	int 	$decimals	Number of decimal points
     * @example
     * 		Assume that current locale is 'vi-VN'
     * 		// Returns '1.000,68'
     * 		L10nHelper::renderNumber(1000.678, 2);

     * 		Assume that current locale is 'en-US'
     * 		// Returns '1,000.68'
     * 		L10nHelper::renderNumber(1000.678, 2);
     *
     */
    public static function renderNumber($value,$decimals=0){

        if($value != null && trim($value) == ''){
            return '';
        }
        if (!is_numeric($value)) {
            return '';
        }
        $locale		=	self::getLocale();
        $symbols 	= 	Zend_Locale_Data::getList($locale,'symbols');
        $res		=	number_format($value, $decimals, $symbols['decimal'], $symbols['group']);
        return $res;
    }
    /**
     * return decimal point according to locale
     */
    public static function decimalPoint() {
        $locale		=	self::getLocale();
        $symbols 	= 	Zend_Locale_Data::getList($locale,'symbols');
        return $symbols['decimal'];

    }
    /**
     * return thousand separator according to locale
     */
    public static function thousandSep() {
        $locale		=	self::getLocale();
        $symbols 	= 	Zend_Locale_Data::getList($locale,'symbols');
        return $symbols['group'];

    }
    /**
     * Returns a PHP number from a localized number string
     *
     * @author 	PPDong, 2009-06-01
     * @param 	string 	$value		Input localized number string
     * @param 	int		$precision	Number of decimal points to get from input string
     * @example
     * 		Assume that current locale is 'vi-VN'
     * 		// Returns 1000.6
     * 		return L10nHelper::getNumber('1000,678', 1);
     */
    public static function getNumber($value,$precision=0){
        $locale	=	self::getLocale();
        if(!Zend_Locale_Format::isNumber($value,array('locale' => $locale))){
            return '';
        }
        $res	=	Zend_Locale_Format::getNumber($value,array('locale' => $locale, 'precision'	=> $precision));
        return $res;
    }

    public static function getYMDorder(){
        $locale		=	self::getLocale();
        $dateFormat	=	Zend_Locale_Data::getContent($locale,'date','short');
        $parts		=	explode('/',$dateFormat);
        $parts[0]	=	strtolower($parts[0]);
        $parts[1]	=	strtolower($parts[1]);
        $parts[2]	=	strtolower($parts[2]);
        $res		=	array();
        for($i=0; $i<3; $i++){
            if(iconv_strpos($parts[$i],'d')!==false){
                $res[$i]	=	'dd';
            }
            elseif(iconv_strpos($parts[$i],'m')!==false){
                $res[$i]	=	'mm';
            }
            else{
                $res[$i]	=	'yyyy';
            }
        }
        return $res;
    }
    /**
     * Returns parts of an input date string
     * @author PPDong, 2009-06-08
     * @param string $value Input date string
     */
    public static function getDateParts($value){
        $pattern1	=	'/^\d{4}[\s:0-9]*$/';
        $pattern2	=	'/^(\d{1,2})[\/-]*(\d{4})[\s:0-9]*$/';
        $pattern3	=	'/^(\d{1,2})[\/-]*(\d{1,2})[\/-]*(\d{0,4})[\s:0-9]*$/';
        $res		=	array(0 => '', 1=>'', 2 => '', 3 => '');

        $part = preg_split("/[\s]+/",$value);
        if (isset($part[1])) {
            $res[3] = $part[1];
        }
        if(preg_match($pattern1, $value, $matches)){
            $res[0]	=	'';
            $res[1]	=	'';
            $res[2]	=	$value;
        }
        elseif(preg_match($pattern2, $value, $matches)){
            $orders	=	self::getYMDorder();
            if($orders[0]=='dd'){
                $res[0]	=	'';
                $res[1]	=	$matches[1];
            }
            else{
                $res[1]	=	'';
                $res[0]	=	$matches[1];
            }
            $res[2]	=	$matches[2];
        }
        elseif(preg_match($pattern3, $value, $matches)){
            $res[0]	=	$matches[1];
            $res[1]	=	$matches[2];
            $res[2]	=	$matches[3];
        }
        return $res;
    }

    public static function getAddress($province='', $district='',  $ward='', $street=''){
        $locale		=	self::getLocale();
        $format	=	Zend_Locale_Data::getContent($locale,'address');
        if(empty($province)){
            $format	=	trim(str_replace('{0}', '', $format));
        }
        else{
            $format	=	trim(str_replace('{0}', $province.",", $format));
        }

        if(empty($district)){
            $format	=	trim(str_replace('{1}', '', $format));
        }
        else{
            $format	=	trim(str_replace('{1}', $district.",", $format));
        }

        if(empty($ward)){
            $format	=	trim(str_replace('{2}', '', $format));
        }
        else{
            $format	=	trim(str_replace('{2}', $ward.",", $format));
        }

        if(empty($street)){
            $format	=	trim(str_replace('{3}', '', $format));
        }
        else{
            $format	=	trim(str_replace('{3}', $street.",", $format));
        }

        if(substr($format,0,1)==","){
            $format	=	trim(substr($format,1));
        }

        if(substr($format,strlen($format)-1==",")){
            $format	=	trim(substr($format,0,strlen($format)-1));
        }
        return $format;
    }
}
?>